<script setup>
import {onMounted, ref} from 'vue'

defineProps({
  msg: String,
})

let animationId;
let analyser;
let frequencyArray;

const byteFrequencyRef = ref();

let audioCtx;

async function getMusic() {
  fetch('/毛不易 - 海上日记.mp3').then(async (response) => {
    const musicBuffer = await response.arrayBuffer();
    console.log('music buffer', musicBuffer);
    await startAudio(musicBuffer);
  })
}

async function startAudio(musicBuffer) {
  audioCtx = new AudioContext({ sampleRate: 48000 });
  analyser = audioCtx.createAnalyser();
  analyser.fftSize = 2048;
  analyser.minDecibels = -100;
  analyser.maxDecibels = -10;
  analyser.smoothingTimeConstant = 0.8

  const bufferLength = analyser.frequencyBinCount;
  frequencyArray = new Uint8Array(bufferLength);

  await audioCtx.audioWorklet.addModule('my-processor.js');
  const myNode = new AudioWorkletNode(audioCtx, 'my-processor');

  analyser.connect(myNode);
  myNode.connect(audioCtx.destination);

  audioCtx.decodeAudioData(musicBuffer, function(buffer) {
    console.log(buffer)
    const bufferSource = audioCtx.createBufferSource();
    bufferSource.buffer = buffer;
    bufferSource.connect(analyser);
    bufferSource.start();
  }, function(e) {
    console.error("Error with decoding audio data: " + e.err);
  });

  animationId = requestAnimationFrame(draw);
}

function stopAudio() {
  audioCtx.close();
  cancelAnimationFrame(animationId);
}

function draw() {
  animationId = requestAnimationFrame(draw);
  analyser.getByteFrequencyData(frequencyArray);
  // console.log(frquencyArray);
  drawByteFrequency(frequencyArray);
}

function drawByteFrequency(frequencyArray) {
  const canvas = byteFrequencyRef.value;
  const ctx = canvas.getContext('2d');

  const maxBarHeight = canvas.height * 1.0;
  // console.log(canvas.width, canvas.height)
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  const start = Math.floor(frequencyArray.length);
  const filteredArray = frequencyArray;

  const barWidth = (canvas.width / filteredArray.length);
  const barGap = 1;
  let x = 0;

  // console.log(filteredArray)

  for (let i = 0; i < filteredArray.length; i++) {
    const barHeight = Math.min((filteredArray[i] / 255) * maxBarHeight, maxBarHeight);

    ctx.fillStyle = `rgb(255,0,0)`;
    const y = canvas.height - barHeight;

    ctx.fillRect(x, y, barWidth, barHeight);
    x += barWidth + barGap;
  }
}
</script>

<template>
  <div class="wave-container">
    <button @click="getMusic">开始音乐</button>
    <button @click="stopAudio">停止音乐</button>
    <canvas id="byteFrequency" ref="byteFrequencyRef" class="frequencyCanvas" width="800" height="400"></canvas>
  </div>
</template>

<style scoped>
.wave-container {
  width: 100%;
  height: 100%;
  display: flex;
}

.frequencyCanvas {
  background-color: lightcyan;
}
</style>